home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / language / asxsrc.arc / ASOUT.C < prev    next >
C/C++ Source or Header  |  1991-06-10  |  7KB  |  441 lines

  1. /* asout.c */
  2.  
  3. /*
  4.  * (C) Copyright 1989
  5.  * All Rights Reserved
  6.  *
  7.  * Alan R. Baldwin
  8.  * 721 Berkeley St.
  9.  * Kent, Ohio  44240
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <setjmp.h>
  14. #include "asm.h"
  15.  
  16. #define  R_WORD    0    /* 16 bit */
  17. #define     R_BYTE 01
  18.  
  19. #define     R_AREA    0    /* Base type */
  20. #define  R_SYM    02
  21.  
  22. #define     R_NORM    0    /* PC adjust */
  23. #define     R_PCR    04
  24.  
  25. #define     R_DEF    00    /* Global def. */
  26. #define     R_REF    01    /* Global ref. */
  27. #define     R_REL    00    /* Relocatable */
  28. #define  R_ABS    02    /* Absolute */
  29. #define  R_GBL    00    /* Global */
  30. #define  R_LCL    04    /* Local */
  31.  
  32. #define     NTXT    16
  33. #define     NREL    16
  34.  
  35. char     txt[NTXT];
  36. char     rel[NREL];
  37.  
  38. char    *txtp = { &txt[0] };
  39. char    *relp = { &rel[0] };
  40.  
  41. /*
  42.  * Output absolute byte.
  43.  */
  44. VOID
  45. outab(b)
  46. {
  47.     if (pass == 2) {
  48.         out_lb(b);
  49.         if (oflag) {
  50.             outchk(1, 0);
  51.             *txtp++ = lobyte(b);
  52.         }
  53.     }
  54.     ++dot->s_addr;
  55. }
  56.  
  57. /*
  58.  * Output absolute word.
  59.  * Low then high.
  60.  */
  61. VOID
  62. outaw(w)
  63. {
  64.     if (pass == 2) {
  65.         out_lw(w);
  66.         if (oflag) {
  67.             outchk(2, 0);
  68.             out_tw(w);
  69.         }
  70.     }
  71.     dot->s_addr += 2;
  72. }
  73.  
  74. /*
  75.  * Output relocatable byte.
  76.  */
  77. VOID
  78. outrb(esp, pcrf)
  79. register struct expr *esp;
  80. {
  81.     register n, r;
  82.  
  83.     if (pass == 2) {
  84.         out_lb(esp->e_addr);
  85.         if (oflag) {
  86.             if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
  87.                 outchk(1, 0);
  88.                 *txtp++ = lobyte(esp->e_addr);
  89.             } else {
  90.                 outchk(1, 4);
  91.                 *txtp++ = lobyte(esp->e_addr);
  92.                 r = R_BYTE;
  93.                 if (pcrf)
  94.                     r |= R_PCR;
  95.                 if (esp->e_flag) {
  96.                     n = esp->e_base.e_sp->s_ref;
  97.                     r |= R_SYM;
  98.                 } else {
  99.                     n = esp->e_base.e_ap->a_ref;
  100.                 }
  101.                 *relp++ = r;
  102.                 *relp++ = txtp - txt - 1;
  103.                 out_rw(n);
  104.             }
  105.         }
  106.     }
  107.     ++dot->s_addr;
  108. }
  109.  
  110. /*
  111.  * Output relocatable word.
  112.  * Low then high.
  113.  */
  114. VOID
  115. outrw(esp, pcrf)
  116. register struct expr *esp;
  117. {
  118.     register n, r;
  119.  
  120.     if (pass == 2) {
  121.         out_lw(esp->e_addr);
  122.         if (oflag) {
  123.             if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
  124.                 outchk(2, 0);
  125.                 out_tw(esp->e_addr);
  126.             } else {
  127.                 outchk(2, 4);
  128.                 out_tw(esp->e_addr);
  129.                 r = R_WORD;
  130.                 if (pcrf)
  131.                     r |= R_PCR;
  132.                 if (esp->e_flag) {
  133.                     n = esp->e_base.e_sp->s_ref;
  134.                     r |= R_SYM;
  135.                 } else {
  136.                     n = esp->e_base.e_ap->a_ref;
  137.                 }
  138.                 *relp++ = r;
  139.                 *relp++ = txtp - txt - 2;
  140.                 out_rw(n);
  141.             }
  142.         }
  143.     }
  144.     dot->s_addr += 2;
  145. }
  146.  
  147. /*
  148.  * Clear out any bufferred text and relocation information
  149.  */
  150. VOID
  151. outall()
  152. {
  153.     if (oflag && pass==2)
  154.         outbuf();
  155. }
  156.  
  157. /*
  158.  * Check text buffer and relocation buffer.
  159.  */
  160. VOID
  161. outchk(nt, nr)
  162. {
  163.     register struct area *ap;
  164.  
  165.     if (txtp+nt > &txt[NTXT] || relp+nr > &rel[NREL]) {
  166.         outbuf();
  167.     }
  168.     if (txtp == txt) {
  169.         out_tw(dot->s_addr);
  170.         if (ap = dot->s_area) {
  171.             *relp++ = R_WORD|R_AREA;
  172.             *relp++ = 0;
  173.             out_rw(ap->a_ref);
  174.         }
  175.     }
  176. }
  177.  
  178. /*
  179.  * Output any bufferred text and relocation information
  180.  */
  181. VOID
  182. outbuf()
  183. {
  184.     if (txtp > &txt[2]) {
  185.         fprintf(ofp, "T");
  186.         out(txt, txtp-txt);
  187.         fprintf(ofp, "\n");
  188.         txtp = txt;
  189.         if (relp > rel) {
  190.             fprintf(ofp, "R");
  191.             out(rel, relp-rel);
  192.             fprintf(ofp, "\n");
  193.             relp = rel;
  194.         }
  195.     } else {
  196.         txtp = txt;
  197.         relp = rel;
  198.     }
  199. }
  200.  
  201. /*
  202.  * Walk through the symbol table and the
  203.  * area list and put out the global
  204.  * symbol information at the front of the
  205.  * relocatable file. This routine is also
  206.  * responsible for setting up the reference
  207.  * numbers in the symbol tabel.
  208.  */
  209. VOID
  210. outgsd()
  211. {
  212.     register struct area *ap;
  213.     register struct sym  *sp;
  214.     register i, j;
  215.     char *ptr;
  216.     int c, narea, nglob, rn;
  217.  
  218.     narea = areap->a_ref + 1;
  219.     nglob = 0;
  220.     for (i = 0; i < NHASH; ++i) {
  221.         sp = symhash[i];
  222.         while (sp) {
  223.             if (sp->s_flag&S_GBL)
  224.                 ++nglob;
  225.             sp = sp->s_sp;
  226.         }
  227.     }
  228.     if (xflag == 0) {
  229.         fprintf(ofp, "X%c\n", hilo ? 'H' : 'L');
  230.         fprintf(ofp, "H %X areas %X global symbols\n", narea, nglob);
  231.     } else
  232.     if (xflag == 1) {
  233.         fprintf(ofp, "Q%c\n", hilo ? 'H' : 'L');
  234.         fprintf(ofp, "H %o areas %o global symbols\n", narea, nglob);
  235.     } else
  236.     if (xflag == 2) {
  237.         fprintf(ofp, "D%c\n", hilo ? 'H' : 'L');
  238.         fprintf(ofp, "H %u areas %u global symbols\n", narea, nglob);
  239.     }        
  240.  
  241.     /*
  242.      * Module name
  243.      */
  244.     if (module[0]) {
  245.         fprintf(ofp, "M ");
  246.         ptr = &module[0];
  247.         while (ptr < &module[NCPS]) {
  248.             if (c = *ptr++)
  249.                 putc(c, ofp);
  250.         }
  251.         putc('\n', ofp);
  252.     }
  253.  
  254.     /*
  255.      * Global references and absolutes.
  256.      */
  257.     rn = 0;
  258.     for (i=0; i<NHASH; ++i) {
  259.         sp = symhash[i];
  260.         while (sp) {
  261.             if (sp->s_area==NULL && sp->s_flag&S_GBL) {
  262.                 sp->s_ref = rn++;
  263.                 outsym(sp);
  264.             }
  265.             sp = sp->s_sp;
  266.         }
  267.     }
  268.  
  269.     /*
  270.      * Global relocatables.
  271.      */
  272.     for (i=0; i<narea; ++i) {
  273.         ap = areap;
  274.         while (ap->a_ref != i)
  275.             ap = ap->a_ap;
  276.         outarea(ap);
  277.         for (j=0; j<NHASH; ++j) {
  278.             sp = symhash[j];
  279.             while (sp) {
  280.                 if (sp->s_area==ap && sp->s_flag&S_GBL) {
  281.                     sp->s_ref = rn++;
  282.                     outsym(sp);
  283.                 }
  284.                 sp = sp->s_sp;
  285.             }
  286.         }
  287.     }
  288. }
  289.  
  290. /*
  291.  * Output the relocatable item defining
  292.  * an area.
  293.  */
  294. VOID
  295. outarea(ap)
  296. register struct area *ap;
  297. {
  298.     register char *ptr;
  299.     register c;
  300.  
  301.     fprintf(ofp, "A ");
  302.     ptr = &ap->a_id[0];
  303.     while (ptr < &ap->a_id[NCPS]) {
  304.         if (c = *ptr++)
  305.             putc(c, ofp);
  306.     }
  307.     if (xflag == 0) {
  308.         fprintf(ofp, " size %X flags %X\n", ap->a_size, ap->a_flag);
  309.     } else
  310.     if (xflag == 1) {
  311.         fprintf(ofp, " size %o flags %o\n", ap->a_size, ap->a_flag);
  312.     } else
  313.     if (xflag == 2) {
  314.         fprintf(ofp, " size %u flags %u\n", ap->a_size, ap->a_flag);
  315.     }
  316. }
  317.  
  318. /*
  319.  * Output the relocatable item describing a
  320.  * global symbol.
  321.  */
  322. VOID
  323. outsym(sp)
  324. register struct sym *sp;
  325. {
  326.     register char *ptr;
  327.     register c;
  328.  
  329.     fprintf(ofp, "S ");
  330.     ptr = &sp->s_id[0];
  331.     while (ptr < &sp->s_id[NCPS]) {
  332.         if (c = *ptr++)
  333.             putc(c, ofp);
  334.     }
  335.     fprintf(ofp, " %s", sp->s_type==S_NEW ? "Ref" : "Def");
  336.     if (xflag == 0) {
  337.         fprintf(ofp, "%04X\n", sp->s_addr);
  338.     } else
  339.     if (xflag == 1) {
  340.         fprintf(ofp, "%06o\n", sp->s_addr);
  341.     } else
  342.     if (xflag == 2) {
  343.         fprintf(ofp, "%05u\n", sp->s_addr);
  344.     }
  345. }
  346.  
  347. VOID
  348. out(p, n)
  349. register char *p;
  350. register n;
  351. {
  352.     while (n--) {
  353.         if (xflag == 0) {
  354.             fprintf(ofp, " %02X", (*p++)&0377);
  355.         } else
  356.         if (xflag == 1) {
  357.             fprintf(ofp, " %03o", (*p++)&0377);
  358.         } else
  359.         if (xflag == 2) {
  360.             fprintf(ofp, " %03u", (*p++)&0377);
  361.         }
  362.     }
  363. }
  364.  
  365. /*
  366.  * Output a byte to the listing buffer.
  367.  */
  368. VOID
  369. out_lb(b)
  370. register b;
  371. {
  372.     if (cp < &cb[NCODE])
  373.         *cp++ = b;
  374. }
  375.  
  376. /*
  377.  * Output ordered word to the listing buffer.
  378.  */
  379. VOID
  380. out_lw(n)
  381. register n;
  382. {
  383.     if (hilo) {
  384.         out_lb(hibyte(n));
  385.         out_lb(lobyte(n));
  386.     } else {
  387.         out_lb(lobyte(n));
  388.         out_lb(hibyte(n));
  389.     }
  390. }
  391.  
  392. /*
  393.  * Output ordered 'Relocation' word.
  394.  */
  395. VOID
  396. out_rw(n)
  397. register n;
  398. {
  399.     if (hilo) {
  400.         *relp++ = hibyte(n);
  401.         *relp++ = lobyte(n);
  402.     } else {
  403.         *relp++ = lobyte(n);
  404.         *relp++ = hibyte(n);
  405.     }
  406. }
  407.  
  408. /*
  409.  * Output ordered 'Text' word.
  410.  */
  411. VOID
  412. out_tw(n)
  413. register n;
  414. {
  415.     if (hilo) {
  416.         *txtp++ = hibyte(n);
  417.         *txtp++ = lobyte(n);
  418.     } else {
  419.         *txtp++ = lobyte(n);
  420.         *txtp++ = hibyte(n);
  421.     }
  422. }
  423.  
  424. /*
  425.  * Extract low half of a word.
  426.  */
  427. int
  428. lobyte(n)
  429. {
  430.     return (n&0377);
  431. }
  432.  
  433. /*
  434.  * Extract high half of a word.
  435.  */
  436. int
  437. hibyte(n)
  438. {
  439.     return ((n>>8)&0377);
  440. }
  441.